﻿#include <QtGui>
#include <QString>
#include <QDialog>
#include <QThread>
#include <QProcess>
#include <QTabWidget>
#include <QApplication>
#include <QProgressDialog>
#include <qtconcurrentrun.h>

#include "MainWindow.h"

extern CCoreSPCN *pSPCN;
extern config	*cfg;

CMainWindow::CMainWindow(QWidget *parent, Qt::WFlags flags)
	:  QMainWindow(parent, flags)
{
	formConfig = NULL;
	pSPCN = new CCoreSPCN;
	cfg = new config;
	pSPCN->Init();

	setupWidget();
	setupActions();
	setupPlot();
	setupTable();
	setupMenuBar();
	setupToolBars();
	setupDockWidg();
	setupStatusBar();
	/*WidgMain->setLayout(layoutMain);*/
	setCentralWidget(plotHist);
}

CMainWindow::~CMainWindow()
{
	delete pSPCN;
	delete cfg;
}
// 
int CMainWindow::runPerforms()
{
	performsAct->setEnabled(false);
	//TabPlot->setTabEnabled (1, false );
	//clearData();
	// очищаем все ранее сгенерированные файлы и
	// устанавливаем параметры вычислений если
	// это не импортированные данные
	if (!pSPCN->setting.isImportMtr)
	{
		pSPCN->clearDataFile();
		cfg->nPerf = tbSet->_spinBox.at(0)->value();
		cfg->mSize = tbSet->_spinBox.at(1)->value();
		cfg->idLaw = tbSet->_comboBox.at(0)->currentIndex();

		// устанавливаем параметры и запускаем процесс вычислений
		// в соответствии с настройками
		pSPCN->setNExp(cfg->nPerf);
		pSPCN->setMtrSize(cfg->mSize);
		pSPCN->setDistLaw(cfg->idLaw);
		pSPCN->setEpsStat(cfg->epsCond);
	}
	pSPCN->run();	// запуск процесса вычислений
	// 
	if (pSPCN->setting.usingThreading)		// TODO: /review/
	{
		if (cfg->nPerf < 200 || cfg->mSize < 20 )	
			timer->start();

		progDialog->setRange(0,cfg->nPerf);
		timer->start(1000);
		progDialog->show();
	}
	else
	{
		updateDataWidget();
	}
return 0;
}
///////////////////////////////////////////////////////////////////////////
// останавливает поток вычислений
int CMainWindow::stopPerforms()
{
	pSPCN->StopPerforms();
	clearData();
	progDialog->hide();
	timer->stop();
	performsAct->setEnabled(true);
return 0;
}
///////////////////////////////////////////////////////////////////////////
// callback ф-ция вызывается при изменении статуса вычисления
void CMainWindow::sendProgress()
{
	emit BeginProgress(pSPCN->getNowPerfom());

	if (pSPCN->getNowPerfom() == cfg->nPerf)
	{
		emit DoneProgress();
		progDialog->hide();
		timer->stop();
	}
}
///////////////////////////////////////////////////////////////////////////
// настройка/создание всех взаимодействий в приложении
void CMainWindow::setupActions()
{
	importAct = new QAction(QIcon(":/layer_import.png"),tr("&Import data"), this);
	importAct->setStatusTip(tr("Import data to application"));
	connect(importAct, SIGNAL(triggered()), this, SLOT(importData()));
	// export
	exportCondAct = new QAction(QIcon(":/table_heatmap.png"),tr("&Cond Number"), this);
	exportCondAct->setStatusTip(tr("Export Cond Number in text File"));
	connect(exportCondAct, SIGNAL(triggered()), this, SLOT(exportCond()));

	exportCondMatLabAct = new QAction(QIcon(":/exportCondMatLab.png"),tr("&Cond MatLab"), this);
	exportCondMatLabAct->setStatusTip(tr("Export Cond Number to MatLab"));
	connect(exportCondMatLabAct, SIGNAL(triggered()), this, SLOT(exportCondMatLab()));

	exportMtrAct = new QAction(QIcon(":/table_export.png"),tr("&All Matrixs"), this);
	exportMtrAct->setStatusTip(tr("Export all generics matrixs in file"));
	connect(exportMtrAct, SIGNAL(triggered()), this, SLOT(exportMatrix()));
	// open/save
	openFileAct = new QAction(QIcon(":/layer_open.png"),tr("&Open file"), this);
	openFileAct->setStatusTip(tr("Open result file"));
	connect(openFileAct, SIGNAL(triggered()), this, SLOT(openData()));

	saveFileAct = new QAction(QIcon(":/page_save.png"),tr("&Save file"), this);
	saveFileAct->setStatusTip(tr("Save result file"));
	connect(saveFileAct, SIGNAL(triggered()), this, SLOT(saveData()));
	saveFileAct->setEnabled(false);
	// do ection
	quitAct = new QAction(tr("&Quit"), this);
	quitAct->setShortcuts(QKeySequence::Quit);
	quitAct->setStatusTip(tr("Quit the application"));
	connect(quitAct, SIGNAL(triggered()), this, SLOT(close()));

	performsAct = new QAction(QIcon(":/things_digital.png"), tr("&Calculation  Cond. Numbers"), this);
	performsAct->setStatusTip(tr("Run the calculation of the condition number"));
	connect(performsAct, SIGNAL(triggered()), this, SLOT(runPerforms()));

	plotCondAct = new QAction(QIcon(":/layer_his.png"), tr("&Histogram"), this);
	plotCondAct->setStatusTip(tr("Histogram Conditions Numbers"));

	sortCondDownAct = new QAction(QIcon(":/sort_descending.png"),tr("Sorting Up"), this);
	sortCondDownAct->setStatusTip(tr("Sorting Conditions Numbers"));
	connect(sortCondDownAct, SIGNAL(triggered()), this, SLOT(sortCondUP()));
	sortCondDownAct->setEnabled(false);

	sortCondUpAct = new QAction(QIcon(":/sort_ascending.png"),tr("Sorting Down"), this);
	sortCondUpAct->setStatusTip(tr("Sorting Conditions Numbers"));
	connect(sortCondUpAct, SIGNAL(triggered()), this, SLOT(sortCondDown()));
	sortCondUpAct->setEnabled(false);

	unsortCondAct = new QAction(QIcon(":/unsort_minus-sort-icon.png"),tr("Unsorting"), this);
	unsortCondAct->setStatusTip(tr("Unsorting Conditions Numbers"));
	connect(unsortCondAct, SIGNAL(triggered()), this, SLOT(unsortCond()));
	unsortCondAct->setEnabled(false);

	funcDistAct = new QAction(QIcon(":/statistics.png"),tr("Statistics Info"), this);
	funcDistAct->setStatusTip(tr("Sattistics information Condition numbers"));
	//connect(funcDistAct, SIGNAL(triggered()),StatCond, SLOT(getStatisticInfo()));
	connect(funcDistAct, SIGNAL(triggered()),this, SLOT(updateStatisticWidget()));

	funcDistAct->setEnabled(false);

	clearHistoryAct = new QAction(QIcon(":/draw_eraser.png"), tr("&Clear History"), this);
	connect(clearHistoryAct, SIGNAL(triggered()), this, SLOT(clearData()));
	clearHistoryAct->setEnabled(false);

	configAct = new QAction(QIcon(":/setting_tools.png"), tr("&Options"), this);
	configAct->setStatusTip(tr("Options SPCN"));
	connect(configAct, SIGNAL(triggered()), ConfDialog, SLOT(show()));
}
///////////////////////////////////////////////////////////////////////////
// создаем меню
void CMainWindow::setupMenuBar()
{
	fileMenu = new QMenu;
	fileMenu = menuBar()->addMenu(tr("&File")); 
	fileMenu->addAction(openFileAct);
	fileMenu->addAction(saveFileAct);
	fileMenu->addSeparator();
	fileMenu->addAction(importAct);
	exportMenu = fileMenu->addMenu(QIcon(":/layer_export.png"),tr("&Export"));
	exportMenu->addAction(exportCondAct);
	exportMenu->addAction(exportCondMatLabAct);
	exportMenu->addAction(exportMtrAct);
	fileMenu->addSeparator();

	QAction *action = fileMenu->addAction(tr("Quit"));
	connect(action, SIGNAL(triggered()), this, SLOT(close()));
	
	QMenu *viewMenu = menuBar()->addMenu(tr("&View"));
	action = viewMenu->addAction(tr("Show All"));

	QMenu *modelingMenu =  menuBar()->addMenu(tr("&Modeling"));
	modelingMenu->addAction(performsAct);
	modelingMenu->addSeparator();
	modelingMenu->addAction(plotCondAct);

	QMenu *toolsMenu = menuBar()->addMenu(tr("&Tools"));
	toolsMenu->addAction(funcDistAct);
	toolsMenu->addSeparator();
	toolsMenu->addAction(sortCondDownAct);
	toolsMenu->addAction(sortCondUpAct);
	toolsMenu->addAction(unsortCondAct);
	toolsMenu->addSeparator();
	toolsMenu->addAction(configAct);
	
	QMenu *aboutMenu = menuBar()->addMenu(tr("&Help"));
	action = aboutMenu->addAction(tr("About"));
	connect(action, SIGNAL(triggered()), this, SLOT(about()));
}
///////////////////////////////////////////////////////////////////////////
// создание панели инструментов
void CMainWindow::setupToolBars()
{
	QFont f("Helvetica", 8, QFont::Bold);
	
	tbFile = new ToolBar("Files ToolBar",this);
	addToolBar(tbFile);
	tbFile->addAction(openFileAct);
	tbFile->addAction(saveFileAct);
	tbFile->addSeparator();
	tbFile->addAction(importAct);

	tbFile->addAction(exportMenu->menuAction());
	exportMenu->setEnabled(false);
	tbModeling = new ToolBar("Modeling ToolBar", this);
	addToolBar(tbModeling);
	tbModeling->addAction(performsAct);
	tbModeling->addSeparator();

	tbPlot = new ToolBar("Plot ToolBar",this);
	addToolBar(tbPlot);
	tbPlot->addAction(clearHistoryAct);
	//
	tbOptions = new ToolBar("Options ToolBar",this);
	addToolBar(tbOptions);
	tbOptions->addAction(configAct);
	//
	tbTools = new ToolBar("Tools ToolBar",this);
	addToolBar(Qt::RightToolBarArea,tbTools);
	tbTools->addAction(funcDistAct);
	tbTools->addSeparator();
	tbTools->addAction(sortCondUpAct);
	tbTools->addAction(sortCondDownAct);
	tbTools->addSeparator();
	tbTools->addAction(unsortCondAct);
	//
	addToolBarBreak(Qt::ToolBarArea::TopToolBarArea);
	tbSet = new ToolBar("Settings ToolBar",this);
	QLabel *labelBox = new QLabel("Law dist: ");
	tbSet->addWidget(labelBox);
	QStringList qstrList;
	qstrList <<"Exp"<<"Normal"<<"Cauchy"<<"Lognormal"<<"Uniform";
	tbSet->addComboBox(&qstrList,&f);
	QLabel *labelPerf = new QLabel("Performs n: ");
	tbSet->addWidget(labelPerf);
	tbSet->addSpinBox();
	tbSet->_spinBox.at(0)->setValue(100);
	tbSet->_spinBox.at(0)->setSingleStep(50);
	QLabel *labelMatrix = new QLabel("Dimension m: ");
	tbSet->addWidget(labelMatrix);
	tbSet->addSpinBox();
	tbSet->_spinBox.at(1)->setValue(10);
	tbSet->_spinBox.at(1)->setMinimum(2);
	tbSet->_spinBox.at(1)->setSingleStep(2);
	tbSet->endPart();
	//QLabel *labelEps = new QLabel("Epsilon Cond: ");
	//tbSet->addWidget(labelEps);
	//dSpinBoxEps = new QDoubleSpinBox;
	//dSpinBoxEps->setMaximum(1);
	//dSpinBoxEps->setSingleStep(0.01);
	//dSpinBoxEps->setValue(1.0);
	//tbSet->addWidget(dSpinBoxEps);
	addToolBar(tbSet);
	//
}
///////////////////////////////////////////////////////////////////////////
// создание открепляемых окон
void CMainWindow::setupDockWidg()
{
	// доступные области для стыковки
	// setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
	// setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
	setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
	setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
	// DockWidget - генерированых матриц
	DockWidget *dwInfoMtr = new DockWidget(tr("Matrix View"), this, 0);
	dwInfoMtr->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
	addDockWidget(Qt::BottomDockWidgetArea, dwInfoMtr);
	//
	QHBoxLayout *layoutTable = new QHBoxLayout;
	layoutTable->addWidget(tableMtr);
	dwInfoMtr->widg->setLayout(layoutTable);
	dwInfoMtr->setupDocWidget();

	// DockWidget - график интегральной ф-ции распред.
	dwPlotStatInfo = new DockWidget(tr("Plot Integr"), this, 0);
	dwPlotStatInfo->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
	addDockWidget(Qt::NoDockWidgetArea, dwPlotStatInfo);

	dwPlotStatInfo->setVisible(false);
	dwPlotStatInfo->setFloating(true); // неприкреплен по умолчанию
	//
	QVBoxLayout *layoutstat = new QVBoxLayout;
	// *vbl = new QVBoxLayout;
	layoutstat->addWidget(new QLabel("Frequancy Function"));
	layoutstat->addWidget(plotFuncFreq);
	layoutstat->addWidget(new QLabel("Integral Function Dimension"));
	layoutstat->addWidget(plotFuncIntegral);
	dwPlotStatInfo->widg->setLayout(layoutstat);
	dwPlotStatInfo->setupDocWidget();

	// DockWidget - таблицы чисел обусловленности
	dwTableCond = new DockWidget(tr("Cond Number"), this, 0);
	dwTableCond->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
	addDockWidget(Qt::RightDockWidgetArea, dwTableCond);
	//
	QVBoxLayout *layoutCondNum = new QVBoxLayout;
	layoutCondNum->addWidget(tableCond);
	dwTableCond->widg->setLayout(layoutCondNum);
	dwTableCond->setupDocWidget();

	// DockWidget - таблица статистической информации
	dwTableCondStat = new DockWidget(tr("Cond Statistic"), this, 0);
	dwTableCondStat->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
	addDockWidget(Qt::RightDockWidgetArea, dwTableCondStat);
	//
	QVBoxLayout *layoutStat = new QVBoxLayout;
	layoutStat->addWidget(tableStat);
	dwTableCondStat->widg->setLayout(layoutStat);
	dwTableCondStat->setupDocWidget();

	tabifyDockWidget(dwTableCondStat,dwTableCond);
	//
}
//void CMainWindow::dock();
///////////////////////////////////////////////////////////////////////////
void CMainWindow::setupStatusBar()
{
	statusBar()->showMessage(tr("Ready"));
}
///////////////////////////////////////////////////////////////////////////
// создание виджета таблиц
void CMainWindow::setupTable()
{
	tableMtr = new QTableWidget(cfg->mSize,cfg->mSize,this);
	tableCond = new QTableWidget(cfg->nPerf,1,this);
	tableStat = new QTableWidget(cfg->nPerf,2,this);
	tItmsCond = new QTableWidgetItem;
	tItmsMtr = new QTableWidgetItem;
	tItmsStat = new QTableWidgetItem;

	for (int nh=1,i = 0; i < cfg->mSize; i++,nh++){
		tableMtr->horizontalHeader()->resizeSection(nh-1,65);
		for (int nv=1,j = 0; j < cfg->mSize; j++,nv++){
			tableMtr->verticalHeader()->resizeSection(nv-1,19);
		}
	}

	tableCond->verticalHeader()->setVisible(false);
	tableCond->setHorizontalHeaderLabels(QStringList()<<"Condition number");
	tableCond->horizontalHeader()->resizeSection(0,170);
	for (int nv=1,j = 0; j < cfg->nPerf; j++,nv++)
		tableCond->verticalHeader()->resizeSection(nv-1,19);

	tableStat->verticalHeader()->setVisible(false);
	tableStat->setHorizontalHeaderLabels(QStringList()<<"Cond"<<"Freq"<<"Relative Freq");

	for (int nv = 1,j = 0; j < cfg->nPerf; j++, nv++)
		tableStat->verticalHeader()->resizeSection(nv - 1,19);

	connect(tableCond, SIGNAL(cellClicked(int,int)), this, SLOT(updateTableMtr(int)));
	connect(tableCond->verticalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(updateTableMtr(int)));
}
///////////////////////////////////////////////////////////////////////////
// формирование виджета графика
void CMainWindow::setupPlot()
{
	plotHist = new Plot;
	plotHist->setupHistogram();
	plotFuncFreq = new Plot;
	plotFuncFreq->setupFunction();
	plotFuncIntegral = new Plot;
	plotFuncIntegral->setupFunction();

	/*TabPlot = new QTabWidget;*/

	//TabPlot->addTab(plotHist, tr("Cond Data")); 
	//QSplitter *qsplit = new QSplitter(TabPlot);
	//qsplit->addWidget(plotFreq);
	//qsplit->addWidget(plotFuncIntegral);
	//qsplit->setOrientation(Qt::Vertical);
	//TabPlot->addTab(qsplit, tr("Dist Function"));
	////TabGraph->setTabPosition(TabPosition::South);
	//TabPlot->setTabEnabled (1, false );
	//layoutMain->addWidget(TabPlot);
}
///////////////////////////////////////////////////////////////////////////
// создание всех второстипенных форм
void CMainWindow::setupWidget()
{
	ConfDialog = new Config;

	WidgMain = new QWidget;
	layoutMain = new QVBoxLayout;

	progDialog = new QProgressDialog;
	progDialog->setWindowModality(Qt::WindowModal);
	connect(progDialog, SIGNAL(canceled()), this, SLOT(stopPerforms()));
	
	connect(this, SIGNAL(BeginProgress(int)),progDialog,SLOT(setValue(int)));
	connect(this, SIGNAL(DoneProgress()),SLOT(updateDataWidget()));

	timer = new QTimer(this);
	connect(timer, SIGNAL(timeout()), this, SLOT(sendProgress()));
}
///////////////////////////////////////////////////////////////////////////
// обновление всех виджетов представления данных
void CMainWindow::updateDataWidget()
{	// увеличиваем число проводимых экспирементов
	cfg->coutModeling++;
	// обновляем таблицы
	if(pSPCN->setting.isTableCond)
	{
		updateTableCond();
		cfg->currMtr = -1;		// для предотвращения бага
		updateTableMtr(0);
	}
	// обновляем графики
	if(pSPCN->setting.isHistogramCond)
	{
		updateHistogram();
	}
	tbSet->setEnabled( true );
	funcDistAct->setEnabled( true );
	exportMenu->setEnabled( true );
	performsAct->setEnabled( true );
	saveFileAct->setEnabled( true );
	unsortCondAct->setEnabled(true);
	sortCondDownAct->setEnabled( true );
	sortCondUpAct->setEnabled( true );
	clearHistoryAct->setEnabled( true );
	//TabPlot->setCurrentIndex(0);
	tabifyDockWidget(dwTableCondStat,dwTableCond);
}
///////////////////////////////////////////////////////////////////////////
// обновление таблицы чисел обусловленности матриц
void  CMainWindow::updateTableCond()
{
	tableCond->setRowCount(cfg->nPerf);
	
	// формируем элементы таблицы чисел обусловленности
	for(int nv = 1,j = 0; j < cfg->nPerf; j++,nv++)
	{ 
		int idMtr = pSPCN->CondNum.at(j).id;
		double condMtr = pSPCN->CondNum.at(j).val;
		tItmsCond = new QTableWidgetItem(QIcon(":/bullet_go.png"),
			QString("%1 %2 > = %3").arg("Matrix <").arg(idMtr).arg(condMtr));
		tableCond->verticalHeader()->resizeSection(nv-1,19);
		tableCond->setItem(0,j,tItmsCond);
	}

	tableCond->setFocus();
	tableCond->selectRow(0);
}
///////////////////////////////////////////////////////////////////////////
// обновление таблицы статистики числа обусловленности
void  CMainWindow::updateStatisticWidget()
{
	// если проводились статистические измерения то 
	// чистим данные виджетов перед обновлением
	if (cfg->coutAnaliz)	{	
		plotFuncFreq->clearFunktion();
		plotFuncIntegral->clearFunktion();
		//int var = pSPCN->_statistic.CondStat.size();
		//for (int i = 0; i < cfg->coutAnaliz; i++){
		//	plotFuncFreq->grid.at(i)->setVisible(false);
		//	plotFuncFreq->grid.at(i)->detach();
		//}
		//plotFuncFreq->grid.clear();
		//plotFuncFreq->_dataInterval.clear();

		//plotFuncFreq->d_intervalCurve->setVisible(false);
		//plotFuncFreq->d_intervalCurve->detach();
	}

	pSPCN->CondAnаliz(NULL);

	tableStat->clearContents();

	const int size = pSPCN->_statistic.CondStat.size();
	const int allCond = pSPCN->CondNum.size();

	tableStat->setRowCount(size);
	tableStat->setColumnCount(3);

	tableStat->horizontalHeader()->resizeSection(1,35);
	tableStat->setHorizontalHeaderLabels(QStringList()<<"Cond"<<"Freq"<<"Relative Freq");
		
	for (int i = 0; i <= size; i++)
	{
		double condN = pSPCN->_statistic.CondStat[i].val;
		tableStat->verticalHeader()->resizeSection(i,19);

		tItmsStat = new QTableWidgetItem(QString("%1").arg(condN));
		tableStat->setItem(i,0,tItmsStat);
		tItmsStat->setTextAlignment(Qt::AlignCenter);

		int freq = pSPCN->_statistic.CondStat[i].id;
		tItmsStat = new QTableWidgetItem(QString("%1").arg(freq));
		tableStat->setItem(i,1,tItmsStat);
		tItmsStat->setTextAlignment(Qt::AlignCenter);
		// считаем относительные частоты
		double relFreq = (double)freq / (double)allCond;
		tItmsStat = new QTableWidgetItem(QString("%1").arg(relFreq));
		tableStat->setItem(i,2,tItmsStat);
		tItmsStat->setTextAlignment(Qt::AlignCenter);
	}
	// 

	tabifyDockWidget(dwTableCond,dwTableCondStat);

	plotFuncFreq->populateFunction(0);
	plotFuncIntegral->populateFunction(1);
	dwPlotStatInfo->setVisible(true);
	funcDistAct->setEnabled( false ); 
	cfg->coutAnaliz = 1;
}
///////////////////////////////////////////////////////////////////////////
// обновление выделенной таблицы матриц 
int CMainWindow::updateTableMtr(int selectRow)
{	// если матрицы равны то нет смысла их обновлять
	if (cfg->currMtr == selectRow) 
		return 1;
	// если нет данных для представления
	if (!cfg->coutModeling || !pSPCN->setting.isTableCond)
	{	
		return -1;
	}
	else{
		cfg->currMtr = selectRow;
	}

	cfg->mSize = pSPCN->getMtrSize();
	cfg->nPerf = pSPCN->getPerfom();
	QStringList qlstH,qlstV;
	QString qstrH,qstrV;
	CMatrix _dataMtr(cfg->mSize,cfg->mSize);
	_dataMtr.fill(0);

	if (pSPCN->setting.usingDisk)
		pSPCN->readMtrFromFile(cfg->currMtr, _dataMtr);
	if (pSPCN->setting.usingMemory)
		pSPCN->readMtrFromMemory(cfg->currMtr, _dataMtr);

	tableMtr->clear();
	tableMtr->setRowCount(cfg->mSize);
	tableMtr->setColumnCount(cfg->mSize);

	// формируем таблицу для представленя матрицы данных
	for (int nh = 1,i = 0; i < cfg->mSize; i++,nh++)
	{
		tableMtr->setHorizontalHeaderLabels(qlstH<<qstrH.number(nh));
		tableMtr->horizontalHeader()->resizeSection(nh-1,65);
		for (int nv=1,j = 0; j < cfg->mSize; j++,nv++)
		{
			tableMtr->setVerticalHeaderLabels(qlstV<<qstrV.number(nv));
			tableMtr->verticalHeader()->resizeSection(nv-1,19);
			// создаем и заполняем элементы таблицы 
			tItmsMtr = new QTableWidgetItem(QString("%1").arg(_dataMtr[i][j]));
			tableMtr->setItem(i,j,tItmsMtr);
			tItmsMtr->setTextAlignment(Qt::AlignCenter);
		}
	}
	// раскрашиваем таблицу
	if (pSPCN->setting.isColorTable)
	{
		int r = 0,g = 0,b = 0;
		QColor colorResult;
		for(int i = 0; i < cfg->mSize; i++)
		{
			for(int j = 0; j < cfg->mSize; j++)
			{
				double val = ( 1 - _dataMtr[i][j]);
				r = ( 1 - val ) * 255;
				g = 255 - r;
				QColor colorR(r,g,0,200);
				tableMtr->item(i,j)->setBackgroundColor(colorR);
			}
		}
	}
return 0;
}
///////////////////////////////////////////////////////////////////////////
// обновление грвфика
void CMainWindow::updateHistogram()
{	
	if(!pSPCN->setting.isHistogramCond) return;

	char buffNameLaw[256];
	memset(buffNameLaw, 0, sizeof(buffNameLaw) );
	Qt::GlobalColor color;
	// присвоение цвета в зависемости от типа распределения
	switch (pSPCN->getLaw())
	{
	case lawNormal: 
		color = Qt::darkCyan;
		break;
	case lawExp:
		color = Qt::darkRed;
		break;
	case lawCauchy:
		color = Qt::darkGreen;
		break;
	case lawLognormal:
		color = Qt::darkYellow;
		break;
	case lawUniform: 
		color = Qt::darkBlue;
		break;
	default:  
		break;
	}
	// в строке имя выбранного закона распределения
	sprintf(buffNameLaw, "%d -> %s", cfg->coutModeling,pSPCN->getLawName());
	// заполняем гистограмму данными
	plotHist->populateHistogram(buffNameLaw,color);
}
///////////////////////////////////////////////////////////////////////////
// показывает директорию сгенерированных файлов	
//void CMainWindow::showResultInFolder()	// TODO: /implements/nouse
//{
//	QTreeWidget twg;
//	QStringList qstrList;
//	qstrList<<"Result Folder";
//	twg.setHeaderLabels(qstrList);
//	twg.setSortingEnabled(true);
//
//	QTreeWidgetItem *pqtwItem = new QTreeWidgetItem(&twg);
//	pqtwItem->setText(0,"Local Disk(C)");
//}
///////////////////////////////////////////////////////////////////////////
// очищает все данные
int CMainWindow::clearData()
{
	if (pSPCN->setting.isHistogramCond)
	{	// очищаем историю гистограмы
		plotHist->clearHistogram();
	}
	// очищаем графики ф-ций
	if (cfg->coutAnaliz)	
	{
		plotFuncFreq->clearFunktion();
		plotFuncIntegral->clearFunktion();
		dwPlotStatInfo->setVisible(false);
	}
	cfg->coutAnaliz = 0;

	// очищаем виджеты таблиц
	tableCond->clearContents();
	tableCond->setRowCount(100);

	tableStat->clearContents();
	tableMtr->clearContents();
	tableMtr->setRowCount(10);
	tableMtr->setColumnCount(10);

	tbSet->setEnabled(true);

	pSPCN->clearDataFile();
	pSPCN->setting.isImportMtr == false;

	/*TabPlot->setTabEnabled (1, false );*/
	clearHistoryAct->setEnabled( false );
	sortCondUpAct->setEnabled( false );
	sortCondDownAct->setEnabled( false );
	unsortCondAct->setEnabled( false );
	saveFileAct->setEnabled( false );
	exportMenu->setEnabled( false );
	funcDistAct->setEnabled( false );

	cfg->coutModeling = 0;
	cfg->currMtr = -1;
return 0;
}
///////////////////////////////////////////////////////////////////////////
// сохранение результатов вычислений
int CMainWindow::saveData()
{
	QFileDialog::Options options;
	options |= QFileDialog::DontUseNativeDialog;
	QString selectedFilter;
	QLabel *saveFileNameLabel = new QLabel;
	char buffNume[256];
	memset(buffNume,0,sizeof(buffNume));
	sprintf(buffNume,"%s_n%d_%dx%d.sp",pSPCN->getLawName(),pSPCN->getPerfom(),
		pSPCN->getMtrSize(),pSPCN->getMtrSize());

	QString fileName = QFileDialog::getSaveFileName(this,
		tr("Save File 'SPCN'"),
		saveFileNameLabel->text()+buffNume,
		tr("'SPCN' Files (*.sp)"),
		&selectedFilter,
		options);

	if (!fileName.isEmpty())
		saveFileNameLabel->setText(fileName);

	if (fileName.isEmpty()) return -1;

	//string to char[]
	char* str_ptr = new char[ fileName.length() + 1 ]();
	strcpy( str_ptr, fileName.toStdString().c_str() );

	pSPCN->saveResult(str_ptr);

	delete[] str_ptr;

return 0;
}
///////////////////////////////////////////////////////////////////////////
// загрузка результатов вычислений
int CMainWindow::openData()
{
	QFileDialog::Options options;
	options |= QFileDialog::DontUseNativeDialog;
	QString selectedFilter;
	QLabel *openFileNameLabel = new QLabel;
	//openFileNameLabel->setFrameStyle(frameStyle);

	QString fileName = QFileDialog::getOpenFileName(this,
		tr("Open File 'SPCN'"),
		openFileNameLabel->text(),
		tr("'SPCN' Files (*.sp);;Text Files (*.txt)"),
		&selectedFilter,
		options);
	if (!fileName.isEmpty())
		openFileNameLabel->setText(fileName);

	if (fileName.isEmpty()) return -1;

	//string to char[]
	char* str_ptr = new char[ fileName.length() + 1 ]();
	strcpy( str_ptr, fileName.toStdString().c_str() );

	clearData();
	pSPCN->loadResult(str_ptr);
	delete[] str_ptr;
	cfg->nPerf = pSPCN->getPerfom();

	tbSet->_spinBox.at(0)->setValue(cfg->nPerf);
	tbSet->_comboBox.at(0)->setCurrentIndex(pSPCN->getLaw());

	updateDataWidget();
return 0;
}
///////////////////////////////////////////////////////////////////////////
// импортирование коре. матриц в программу
int CMainWindow::importData()
{
	pSPCN->setting.isImportMtr = true;

	QFileDialog::Options options;
	options |= QFileDialog::DontUseNativeDialog;
	QString selectedFilter;
	QLabel *openFileNameLabel = new QLabel;

	QString fileName = QFileDialog::getOpenFileName(this,
		tr("Select text File '*.txt'"),
		openFileNameLabel->text(),
		tr("'text' Files (*.txt);;Text Files (*.txt)"),
		&selectedFilter,
		options);
	if (!fileName.isEmpty())
		openFileNameLabel->setText(fileName);

	if (fileName.isEmpty())
	{
		pSPCN->setting.isImportMtr = false;
		return -1;
	}

	//string to char[]
	char* str_ptr = new char[ fileName.length() + 1 ]();
	strcpy( str_ptr, fileName.toStdString().c_str() );

	clearData();
	pSPCN->importMatix(str_ptr);
	delete[] str_ptr;

	cfg->nPerf = pSPCN->getPerfom();
	cfg->mSize = pSPCN->getMtrSize();
	tbSet->setEnabled(false);

	// выводим сообщение об успешном импорте
	QMessageBox::StandardButton reply;
	char buffMSG[256];
	sprintf(buffMSG, "Import <b>%d</b> matrix dimensions (<b>%d</b>x<b>%d</b>) was succesfully!",
		cfg->nPerf,cfg->mSize,cfg->mSize);
	reply = QMessageBox::information(this, tr("Import succes"),tr(buffMSG));
	
	cfg->coutModeling++;
	updateTableCond();
	updateTableMtr(0);
	cfg->coutModeling--;		// для предотвращения бага

	// запрос на вычисление числа обусловленности для матриц
	QMessageBox msgBox;
	msgBox.setText("Matrix Alredy for Calculation Condition Number");
	msgBox.setInformativeText("<b>Run calculation Now or Later </b>");
	msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
	msgBox.setDefaultButton(QMessageBox::Yes);
	int ret = msgBox.exec();

	switch (ret) {
	case QMessageBox::Yes:
		{
			runPerforms();
			clearHistoryAct->setEnabled(true);
		}break;
	case QMessageBox::No:
		{
			clearHistoryAct->setEnabled(true);
			
		}break;
	case QMessageBox::Cancel:
		{
			clearData();
			clearHistoryAct->setEnabled(false);
			pSPCN->setting.isImportMtr = false;
			tbSet->setEnabled(true);
			
		}break;
	default:
		break;
	}
return 0;
}
///////////////////////////////////////////////////////////////////////////
// экспорт чисел обусловленности в файл
void CMainWindow::exportCond()
{
	QFileDialog::Options options;
	options |= QFileDialog::DontUseNativeDialog;
	QString selectedFilter;
	QLabel *saveFileNameLabel = new QLabel;
	char buffNume[256];
	memset(buffNume,0,sizeof(buffNume));
	sprintf(buffNume,"CondNum(%s_n%d_%dx%d).txt", pSPCN->getLawName(),
		cfg->nPerf,cfg->mSize,cfg->mSize);

	QString fileName = QFileDialog::getSaveFileName(this,
		tr("Export Cond Number 'Text'"),
		saveFileNameLabel->text()+buffNume,
		tr("'Formating text' Files (*.txt)"),
		&selectedFilter,
		options);

	if (!fileName.isEmpty())
		saveFileNameLabel->setText(fileName);

	if (fileName.isEmpty()) return;

	//string to char[]
	char* str_ptr = new char[ fileName.length() + 1 ]();
	strcpy( str_ptr, fileName.toStdString().c_str() );

	pSPCN->exportCondNum(str_ptr);
	delete[] str_ptr;
}
// экспорт чисел обусловленности в MatLab
void CMainWindow::exportCondMatLab()
{
	QFileDialog::Options options;
	options |= QFileDialog::DontUseNativeDialog;
	QString selectedFilter;
	QLabel *saveFileNameLabel = new QLabel;
	char buffNume[256];
	memset(buffNume,0,sizeof(buffNume));
	sprintf(buffNume,"CondNumMatLab(%s_n%d_%dx%d).txt", pSPCN->getLawName(),
		cfg->nPerf,cfg->mSize,cfg->mSize);

	QString fileName = QFileDialog::getSaveFileName(this,
		tr("Export Cond to MatLab"),
		saveFileNameLabel->text()+buffNume,
		tr("'Formating text' Files (*.txt)"),
		&selectedFilter,
		options);

	if (!fileName.isEmpty())
		saveFileNameLabel->setText(fileName);

	if (fileName.isEmpty()) return;

	//string to char[]
	char* str_ptr = new char[ fileName.length() + 1 ]();
	strcpy( str_ptr, fileName.toStdString().c_str() );

	pSPCN->exportCondNumToMatLab(str_ptr);
	delete[] str_ptr;
}
///////////////////////////////////////////////////////////////////////////
// экспортирование всех матриц в один файл
void CMainWindow::exportMatrix()
{
	QFileDialog::Options options;
	options |= QFileDialog::DontUseNativeDialog;
	QString selectedFilter;
	QLabel *saveFileNameLabel = new QLabel;
	char buffNume[256];
	memset(buffNume,0,sizeof(buffNume));
	sprintf(buffNume,"Matrixs'%dx%d'(1-%d)_%s.txt",
		cfg->mSize,cfg->mSize,cfg->nPerf,pSPCN->getLawName());

	QString fileName = QFileDialog::getSaveFileName(this,
		tr("Export All generics Matrixs 'Text'"),
		saveFileNameLabel->text()+buffNume,
		tr("'Formating text' Files (*.txt)"),
		&selectedFilter,
		options);

	if (!fileName.isEmpty())
		saveFileNameLabel->setText(fileName);

	if (fileName.isEmpty()) return;

	//string to char[]
	char* str_ptr = new char[ fileName.length() + 1 ]();
	strcpy( str_ptr, fileName.toStdString().c_str() );

	pSPCN->outAllMatrixToFile(str_ptr);
	delete[] str_ptr;
}
//
void CMainWindow::sortCondDown()
{
	pSPCN->sortCondDown();
	updateDataWidget();
}
//
void CMainWindow::sortCondUP()
{
	pSPCN->sortCondUP();
	updateDataWidget();
}
//
void CMainWindow::unsortCond()
{
	pSPCN->unsortCond();
	updateDataWidget();
}
//
void CMainWindow::about()
{
	QMessageBox::about(this, tr("About SPCN"),
		tr("'<b>SPCN</b>'"
		"(<i>The <b>S</b>tatistical <b>P</b>rogram of the <b>C</b>ondition <b>N</b>umber</i>),"
		" © 2011 <i>Vitaly Lyaschenko</i> "
		"<b>lvixhamelion@gmail.com</b>"));
}




